/*
 * Hibiscus is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation; either version 3 of the License,
 * or (at your option) any later version.
 *
 * Hibiscus is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Hibiscus; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 *
 * Copyright (C) 2003 Tetete - http://tetete.hu.
 */
package hu.tetete.hibiscus.propertytree;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;
import android.widget.TextView;
import android.widget.Toast;

import hu.tetete.hibiscus.R;
import hu.tetete.hibiscus.model.MultiSelectProperty;
import hu.tetete.hibiscus.model.OneSelectProperty;
import hu.tetete.hibiscus.model.Property;
import hu.tetete.hibiscus.model.PropertyGroup;
import hu.tetete.hibiscus.propertytree.propertyhandler.MultiSelectHandler;
import hu.tetete.hibiscus.propertytree.propertyhandler.OneSelectListHandler;
import hu.tetete.hibiscus.propertytree.propertyhandler.PropertyGroupHandler;
import hu.tetete.hibiscus.propertytree.propertyhandler.PropertyHandler;
import hu.tetete.hibiscus.propertytree.propertyhandler.UnsupportedPropertyHandler;
import hu.tetete.hibiscus.propertyvalue.PropertyValue;

/**
 * TODO javadoc.
 */
public class PropertyTreeListAdapter extends BaseAdapter {

    /** Logger TAG. */
    @SuppressWarnings("unused")
    private static final String TAG = PropertyTreeListAdapter.class.getName();

    private final Context                      context;
    private final List<PropertyHandler<?, ?>>  children;
    private final PropertyTreeService          propetyTreeService;
    private final Class<? extends Activity>    activityClass;

    /**
     * @param context The context of the expandable list
     * @param childrenPropertyList The children of the main property
     * @param propertyTreeService Service to provide values for the property tree
     * @param activityClass The class where the drill-down will be forwarded.
     */
    public PropertyTreeListAdapter(final Context context,
            final List<Property<?>> childrenPropertyList,
            final PropertyTreeService propertyTreeService,
            final Class<? extends Activity> activityClass) {
        super();
        this.context            = context;
        this.propetyTreeService = propertyTreeService;
        this.activityClass      = activityClass;
        this.children           = new ArrayList<PropertyHandler<?, ?>>(childrenPropertyList.size());
        for (final Property<?> childProperty : childrenPropertyList) {
            this.children.add(getPropertyHandler(childProperty));
        }
    }



    private PropertyHandler<?, ?> getPropertyHandler(final Property<?> property) {
        if (property instanceof OneSelectProperty) {
            return new OneSelectListHandler(this.context, this.propetyTreeService, (OneSelectProperty)property);
        } else if (property instanceof PropertyGroup) {
            return new PropertyGroupHandler((PropertyGroup)property);
        } else if (property instanceof MultiSelectProperty) {
            return new MultiSelectHandler(this.context, this.propetyTreeService, (MultiSelectProperty)property);
        }
        return new UnsupportedPropertyHandler(this.context, property);
    }


    /**
     * @see android.widget.Adapter#getCount()
     */
    @Override
    public int getCount() {
        return this.children.size();
    }

    /**
     * @see android.widget.Adapter#getItem(int)
     */
    @Override
    public Object getItem(final int position) {
        return this.children.get(position);
    }

    /**
     * @see android.widget.Adapter#getItemId(int)
     */
    @Override
    public long getItemId(final int position) {
        return position;
    }

    /**
     * It can be bind to an onClick event, and it displays the setup view relating to the property.
     */
    private class ShowSetupView implements View.OnClickListener {

        private final PropertyHandler<?, ?> propertyHandler;

        public ShowSetupView(final PropertyHandler<?, ?> propertyHandler) {
            this.propertyHandler = propertyHandler;
        }

        @SuppressWarnings("synthetic-access")
        @Override
        public void onClick(final View v) {
            final Dialog dialog = new Dialog(PropertyTreeListAdapter.this.context);
            dialog.setTitle(this.propertyHandler.getProperty().getName());
            dialog.addContentView(this.propertyHandler.getView(), new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
            dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {

                /**
                 * @see android.content.DialogInterface.OnDismissListener#onDismiss(android.content.DialogInterface)
                 */
                @Override
                public void onDismiss(final DialogInterface dialog) {
                    Toast.makeText(PropertyTreeListAdapter.this.context, "Dialog dismiss", Toast.LENGTH_SHORT).show();
                    notifyDataSetChanged();
                }

            });
            dialog.show();
        }
    }

    /**
     * It can be bind to an onClick event to drill down one level in the property tree.
     */
    private class DrillDownOnClickListener implements View.OnClickListener {

        private final PropertyHandler<?, ?> propertyHandler;

        public DrillDownOnClickListener(final PropertyHandler<?, ?> propertyHandler) {
            this.propertyHandler = propertyHandler;
        }

        @SuppressWarnings("synthetic-access")
        @Override
        public void onClick(final View v) {
            Toast.makeText(PropertyTreeListAdapter.this.context, "You selected: " + this.propertyHandler.getProperty().getName(), Toast.LENGTH_LONG).show();
            final Intent intent = new Intent(PropertyTreeListAdapter.this.context, PropertyTreeListAdapter.this.activityClass);
            intent.putExtra("PROPERTY", this.propertyHandler.getProperty()); //TODO use enum!
            PropertyTreeListAdapter.this.context.startActivity(intent);
        }
    }

    /**
     * @see android.widget.Adapter#getView(int, android.view.View, android.view.ViewGroup)
     */
    @Override
    public View getView(final int position, final View convertView, final ViewGroup parent) {
        final PropertyHandler<?, ?> propertyHandler  = this.children.get(position);
        final Property<?>           property         = propertyHandler.getProperty();

        final LayoutInflater       inflater        = (LayoutInflater)this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        final RelativeLayout       view            = (RelativeLayout)inflater.inflate(R.layout.property_label, null);
        final TextView             propertyLabel   = (TextView)view.findViewById(R.id.propertyLabel);
        final Button               drillDownButton = (Button)view.findViewById(R.id.drillDownButton);

        int propertyLabelRightMargin = 40; //drillDownButton.getWidth();
        final View propertyInfo = propertyHandler.getInfoView();
        if (propertyInfo != null) {
            final RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(100, 60);
            layoutParams.addRule(RelativeLayout.LEFT_OF, drillDownButton.getId());
            propertyInfo.setLayoutParams(layoutParams);
            propertyLabelRightMargin += 100;
            view.addView(propertyInfo, 1);
        }


        propertyLabel.setText(property.getName());
        propertyLabel.setMaxHeight(60);
        propertyLabel.setMaxLines(1);
        final RelativeLayout.LayoutParams propertyLabelLayoutParams = (LayoutParams) propertyLabel.getLayoutParams();
        propertyLabelLayoutParams.setMargins(0, 0, propertyLabelRightMargin + 10, 0);

        drillDownButton.setEnabled(isDrillDownEnabled(property));

        drillDownButton.setOnClickListener(new DrillDownOnClickListener(propertyHandler));
        drillDownButton.setFocusable(false);

        if (property instanceof PropertyGroup && isDrillDownEnabled(property)) {
            view.setOnClickListener(new DrillDownOnClickListener(propertyHandler));
        } else {
            view.setOnClickListener(new ShowSetupView(propertyHandler));
        }
        return view;
    }

    private boolean isDrillDownEnabled(final Property<?> property) {
        final HashMap<Long, PropertyValue> values = this.propetyTreeService.getValues();
        return property.isVisible(values); //TODO if there is any viewable component beneth this element.
    }

//    /**
//     * @see android.widget.ExpandableListAdapter#hasStableIds()
//     */
//    @Override
//    public boolean hasStableIds() {
//        return true;
//    }

}
